package com.hooper.iot.viid.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hooper.iot.face.mq.TopicConstants;
import com.hooper.iot.viid.config.ViidSubscribeConfig;
import com.hooper.iot.viid.dto.SubscribeDTO;
import com.hooper.iot.viid.dto.record.*;
import com.hooper.iot.viid.dto.subscribe.add.SubscribeListObject;
import com.hooper.iot.viid.dto.subscribe.query.SubscribeQueryObject;
import com.hooper.iot.viid.feign.ViidSubscribeFeign;
import com.hooper.iot.viid.dto.usmp.CmsCreditRecordDTO;
import com.hooper.iot.viid.dto.usmp.TimeStamp;
import com.hooper.iot.viid.dto.subscribe.add.SubscribeObject;
import com.hooper.iot.viid.dto.subscribe.add.ViidSubscribeDTO;
import com.hooper.iot.viid.service.ViidService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author developerlizhi
 * @date 2022-06-09 14:28:26
 */
@Slf4j
@Service
public class ViidServiceImpl implements ViidService {

    @Resource
    private ViidSubscribeFeign subscribeFeign;

    @Resource
    private ViidSubscribeConfig subscribeConfig;

    @Resource
    private KafkaTemplate<String, String> kafkaTemplate;

    @Override
    public void subscribe(SubscribeDTO subscribeDTO) {
        try {
            String viidQueryResponse = subscribeFeign.query(subscribeDTO.getDevId());
            log.info("设备ID：{}，订阅情况：{}", subscribeDTO.getDevId(), viidQueryResponse);
            JSONObject jsonObject = JSONUtil.parseObj(viidQueryResponse);
            if (jsonObject.containsKey("SubscribeListObject")) {
                // 存在订阅结果
                JSONObject subscribeListObject = jsonObject.getJSONObject("SubscribeListObject");
                JSONArray subscribeObject = subscribeListObject.getJSONArray("SubscribeObject");
                SubscribeQueryObject queryResponse = subscribeObject.get(0, SubscribeQueryObject.class);
                if (queryResponse.getSubscribeStatus() == 0 && queryResponse.getReceiveAddr().equals(subscribeConfig.getNotice())) {
                    log.info("设备ID：{}，订阅有效，且通知地址正确", subscribeDTO.getDevId());
                    return;
                } else {
                    log.info("设备ID：{}，订阅无效，将重新订阅", subscribeDTO.getDevId());
                    // 删除订阅
                    subscribeFeign.del(subscribeDTO.getDevId());
                }
            }
        } catch (Exception e) {
            log.info("设备ID：{}，未订阅", subscribeDTO.getDevId());
        }
        ViidSubscribeDTO viidSubscribeDTO = convert(subscribeDTO);
        subscribeFeign.add(viidSubscribeDTO);
        log.info("设备ID：{}，订阅成功", subscribeDTO.getDevId());
    }

    @Override
    public void acceptAndSendRecord(String message) {
        ViidAccessRecordDTO accessRecordDTO = JSONUtil.toBean(message, ViidAccessRecordDTO.class);
        CmsCreditRecordDTO usmpAccessRecord = convertRecord(accessRecordDTO);
        kafkaTemplate.send(TopicConstants.TOPIC_TDATA_NTY_ENTRANCE, JSONUtil.toJsonStr(usmpAccessRecord));
    }

    private ViidSubscribeDTO convert(SubscribeDTO subscribeDTO) {
        Date startDate = DateUtil.date();
        Date endDate = DateUtil.offset(startDate, DateField.YEAR, 10);
        ViidSubscribeDTO viidSubscribeDTO = new ViidSubscribeDTO();
        SubscribeListObject subscribeListObject = new SubscribeListObject();
        List<SubscribeObject> subscribes = subscribeListObject.getSubscribeObject();
        SubscribeObject subscribeObject = new SubscribeObject();
        subscribeObject.setApplicantName("admin");
        subscribeObject.setApplicantOrg("usmp");
        subscribeObject.setBeginTime(DateUtil.format(startDate, "yyyyMMddhhmmss"));
        subscribeObject.setEndTime(DateUtil.format(endDate, "yyyyMMddhhmmss"));
        subscribeObject.setOperateType(0);
        subscribeObject.setReason("subscribe");
        subscribeObject.setReceiveAddr(subscribeConfig.getNotice());
        subscribeObject.setSubscribeDetail(subscribeConfig.getDetail());
        subscribeObject.setTitle(subscribeConfig.getTitle());
        subscribeObject.setReportInterval(0);
        subscribeObject.setResourceURI(subscribeDTO.getAccessId());
        subscribeObject.setSubscribeID(subscribeDTO.getDevId());
        subscribes.add(subscribeObject);
        viidSubscribeDTO.setSubscribeListObject(subscribeListObject);
        return viidSubscribeDTO;
    }

    private CmsCreditRecordDTO convertRecord(ViidAccessRecordDTO accessRecordDTO) {
        CmsCreditRecordDTO cmsCreditRecordDTO = new CmsCreditRecordDTO();
        SubscribeNotificationObject notificationObject = accessRecordDTO.getSubscribeNotificationListObject().getSubscribeNotificationObject().get(0);
        AccessRecordObject accessRecordObject = notificationObject.getAccessRecordObjectList().getAccessRecordObject().get(0);
        PersonObject personObject = notificationObject.getPersonObjectList().getPersonObject().get(0);
        SubImageInfoObject subImageInfoObject = personObject.getSubImageList().getSubImageInfoObject().get(0);
        cmsCreditRecordDTO.setDevId(notificationObject.getSubscribeID());
        cmsCreditRecordDTO.setDevType("");

        if (ObjectUtil.isNotEmpty(personObject)) {
            cmsCreditRecordDTO.setIdCode(personObject.getIDNumber());
            cmsCreditRecordDTO.setIdType(personObject.getIDType());
            cmsCreditRecordDTO.setUserName(personObject.getName());
            cmsCreditRecordDTO.setPersonnelId("");
            cmsCreditRecordDTO.setRelateDevIP("");
        }

        if (ObjectUtil.isNotEmpty(subImageInfoObject)) {
            cmsCreditRecordDTO.setImagePath(subImageInfoObject.getStoragePath());
            cmsCreditRecordDTO.setImageSourceCode(1);
        }

        if (ObjectUtil.isNotEmpty(accessRecordObject)) {
            cmsCreditRecordDTO.setAccessId(accessRecordObject.getDeviceID());
            cmsCreditRecordDTO.setAccessName("");
            cmsCreditRecordDTO.setAccessrecordId(accessRecordObject.getAccessRecordID());
            cmsCreditRecordDTO.setBusinessCode("entrance");
            cmsCreditRecordDTO.setCardNo(String.valueOf(accessRecordObject.getCardID()));
            cmsCreditRecordDTO.setContentDescription("");
            cmsCreditRecordDTO.setCreditDesc("");
            cmsCreditRecordDTO.setCreditType(accessRecordObject.getPunchResult());
            // TODO 方向可以查询一机一档
            cmsCreditRecordDTO.setDirection(0);
            cmsCreditRecordDTO.setDoorType(2);
            cmsCreditRecordDTO.setNodeArea("");
            cmsCreditRecordDTO.setNodeKey("");
            cmsCreditRecordDTO.setSourceId(accessRecordObject.getSourceID());
            cmsCreditRecordDTO.setUserId(accessRecordObject.getPersonCode());
            cmsCreditRecordDTO.setSourcePosType("Person");
            cmsCreditRecordDTO.setTemperature("0.00");
            cmsCreditRecordDTO.setSourceType("");
            cmsCreditRecordDTO.setTimeStampStr(DateUtil.now());
            cmsCreditRecordDTO.setServerTimeStamp(DateUtil.now());
            Date currentDate = DateUtil.parse(accessRecordObject.getAccessTime(), "yyyyMMddHHmmss");
            cmsCreditRecordDTO.setTimeStamp(toTimeStamp(currentDate));
        }
        return cmsCreditRecordDTO;
    }

    private static TimeStamp toTimeStamp(Date date) {
        TimeStamp timeStamp = new TimeStamp();
        timeStamp.setYear(DateUtil.year(date));
        timeStamp.setMonth(DateUtil.month(date) + 1);
        timeStamp.setDay(DateUtil.dayOfMonth(date));
        timeStamp.setHour(DateUtil.hour(date, true));
        timeStamp.setMinute(DateUtil.minute(date));
        timeStamp.setSecond(DateUtil.second(date));
        return timeStamp;
    }
}
